#ifndef _LISTENER_H_
#define _LISTENER_H_

#include "OgreCamera.h"
#include "OgreFrameListener.h"
#include "OgreRenderWindow.h"
#include "OgreWindowEventUtilities.h"

#include "OIS/OISInputManager.h"
#include "OIS/OISKeyboard.h"
#include "OIS/OISMouse.h"

#include "TwOgreWindowManager.h"
#include "TwOgreWindow.h"

#if defined OIS_LINUX_PLATFORM
#include <X11/Xutil.h>
#endif

class DeviceListener : public Ogre::FrameListener, public Ogre::WindowEventListener,
	public OIS::MouseListener, public OIS::KeyListener
{
public:
	DeviceListener(Ogre::RenderWindow* win, Ogre::Camera* cam, Ogre::SceneManager *sceneMgr);
	~DeviceListener();

	// Frame event callbacks
	bool frameStarted(const Ogre::FrameEvent& evt);
	//bool frameEnded(const Ogre::FrameEvent& evt);

	// Window event callbacks
	virtual void windowResized(Ogre::RenderWindow* rw);
	virtual void windowClosed(Ogre::RenderWindow* rw);

	// Mouse event callbacks
	virtual bool mouseMoved(const OIS::MouseEvent &arg);
	virtual bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id);
	virtual bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id);

	// Keyboard event callbacks
	virtual bool keyPressed(const OIS::KeyEvent &arg);
	virtual bool keyReleased(const OIS::KeyEvent &arg);

    void shutDown() { mExit = true; };
    static void TW_CALL RunCB(void* clientData);
    static void TW_CALL setSkyboxCallback(const void *value, void *clientData);
    static void TW_CALL getSkyboxCallback(void *value, void *clientData);

    Ogre::SceneManager* getSceneMgr() { return mSceneMgr; }

protected:
	OIS::Mouse *mMouse;
	OIS::Keyboard *mKeyboard;
	OIS::InputManager *mInputManager;
    bool mExit;

	Ogre::SceneManager *mSceneMgr;
	Ogre::SceneNode *mCamNode, *mPitchNode;
	Ogre::Camera *camera;
	Ogre::RenderWindow *mWindow;

	bool mContinue;

    Ogre::Degree pitch, yaw;
	Ogre::Vector3 mDirection;

	TwOgre::WindowManager *mWinManager;
	TwOgre::Window *mWin1, *mWin2, *mWin3;
	// Window1 Controls
	TwOgre::ColorVariable *mBgColor, *mBoxColor;
	TwOgre::IntegerVariable *mBoxHeight;
	TwOgre::RealVariable *mBoxRotSpeed, *mFrameRate;
    TwOgre::QuaternionVariable* mCameraOrientation;
    TwOgre::Direction3DVariable* mCameraDirection;
    TwOgre::Position3DVariable* mCameraPosition;
	TwOgre::BoolVariable *mRotateCube, *mSkyBox;
	// Window 2 Controls
	TwOgre::ColorVariable *mWindowColor;
	TwOgre::IntegerVariable *mWindowPosX, *mWindowPosY;
	TwOgre::StringVariable *mWindowName;
    TwOgre::ButtonVariable* theButton;
    TwOgre::SeparatorVariable* theSep;

	Ogre::MaterialPtr mCubeMat;
	Ogre::SceneNode *mCubeNode;

    bool mMouseLock;

#if defined OIS_LINUX_PLATFORM
    Display* mDpy;
#endif

};
#endif
